package com.boyou.sytzc.core.service

import android.app.Service
import com.baidu.location.BDAbstractLocationListener
import com.baidu.location.BDLocation
import org.simple.eventbus.EventBus
import android.content.Intent
import android.os.Handler
import com.baidu.location.LocationClientOption.LocationMode
import com.boyou.sytzc.utils.common.CommonUtil
import com.boyou.sytzc.data.event.GeoHandleTimeChangedEvent
import android.os.IBinder
import android.os.Message
import java.lang.Thread
import java.lang.ref.WeakReference
import java.lang.InterruptedException
import com.boyou.sytzc.data.database.table.GeoLocationDB
import com.boyou.sytzc.data.entity.GeoLocationInfoEntity
import com.boyou.sytzc.utils.app.AppConfig
import org.simple.eventbus.Subscriber
import java.util.*

/**
 * Created by bj on 2015/9/25.
 * 定位服务
 */
class LocationService : Service() {

    companion object {
        /** 经纬度信息 **/
        @JvmField
        var locationInfo: BDLocation? = null

        /** 是否能运行GEO线程 **/
        var isCanRunGeoThread = true
    }

    /** 消息收发器 **/
    private var messageHandler: MessageHandler? = null

    /** Geo线程 **/
    private var geoThread: GeoThread? = null

    private val appConfig by lazy { AppConfig.singleton() }

    private val locationListener: BDAbstractLocationListener =
        object : BDAbstractLocationListener() {
            override fun onReceiveLocation(bdLocation: BDLocation) {
                locationInfo = bdLocation //获取定位数据
                EventBus.getDefault().post(bdLocation)
            }
        }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        messageHandler = MessageHandler(this)
        restartGeoThread()
        var mode = LocationMode.Hight_Accuracy
        if (appConfig.locationMode != 0)
            mode = LocationMode.Device_Sensors
        CommonUtil.getCurrentLocation(this, 3 * 1000, mode, locationListener)
        return START_STICKY
    }

    @Subscriber
    fun onConfigurationChangedEvent(event: GeoHandleTimeChangedEvent?) {
        restartGeoThread()
    }

    private fun restartGeoThread() {
        if (geoThread != null) {
            isCanRunGeoThread = false
            if (!geoThread!!.isInterrupted)
                geoThread?.interrupt()
            geoThread = null
        }
        geoThread = GeoThread(this) //启动GEO线程
        geoThread?.start()
    }

    override fun onDestroy() {
        isCanRunGeoThread = false
        super.onDestroy()
    }

    override fun onBind(intent: Intent): IBinder? = null

    private class GeoThread(service: LocationService) : Thread() {

        private val weakReference: WeakReference<LocationService?> = WeakReference(service)

        init {
            isCanRunGeoThread = true //重新初始化
        }

        override fun run() {
            super.run()
            val locService = weakReference.get()
            while (!isInterrupted && isCanRunGeoThread && locService != null) {
                try {
                    locService.messageHandler
                        ?.obtainMessage(MessageHandler.MSG_SAVE_LOCATION)
                        ?.sendToTarget()
                    // Log.e("时间信息： " + this.getName(), String.valueOf(spacingTime));
                    sleep(AppConfig.singleton().geoSpacingTime * 1000L)
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                    break
                }
            }
        }
    }

    private class MessageHandler(service: LocationService?) : Handler() {

        companion object {
            /** MSG-保存定位信息 **/
            const val MSG_SAVE_LOCATION = 0x00001A
        }

        private val serviceWeakReference: WeakReference<LocationService?> = WeakReference(service)

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            if (serviceWeakReference.get() != null) {
                val service = serviceWeakReference.get()
                if (msg.what == MSG_SAVE_LOCATION) {
                    if (locationInfo != null) {
                        val geoInfo = GeoLocationInfoEntity(
                            0, locationInfo!!.longitude, locationInfo!!.latitude,
                            locationInfo!!.address.address, Date(), false
                        )
                        GeoLocationDB.getInstance(service).put(geoInfo)
                    }
                }
            }
        }

    }
}